﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace BankUtil
{
    /// <summary>
    /// 加解密类
    /// </summary>
    public class EncryptHelper
    {


        ////默认密钥向量
        //private static byte[] IV = { 0x67, 0x51, 0x40, 0x2F, 0xDE, 0x0F, 0x3E, 0x1A };
        //private static string key = "0123456789ABCDEF0123456789ABCDEF";
        ///// <summary>
        ///// DES加密字符串
        ///// </summary>
        ///// <returns>加密成功返回加密后的字符串，失败返回源串</returns>
        //public  string Encrypt(string toEncryptString)
        //{
        //    try
        //    {
        //        if (toEncryptString == null || toEncryptString == "" || toEncryptString == string.Empty)
        //        {
        //            return "";
        //        }
        //        byte[] rgbKey = Encoding.UTF8.GetBytes(key.Substring(0, 8));//
        //        byte[] rgbIV = IV;
        //        byte[] inputByteArray = Encoding.UTF8.GetBytes(toEncryptString);
        //        DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
        //        MemoryStream mStream = new MemoryStream();
        //        CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
        //        cStream.Write(inputByteArray, 0, inputByteArray.Length);
        //        cStream.FlushFinalBlock();
        //        return Convert.ToBase64String(mStream.ToArray());
        //    }
        //    catch
        //    {
        //        return toEncryptString;
        //    }
        //}

        ///// <summary>
        ///// DES解密字符串
        ///// </summary>
        ///// <param name="toDecryptString">待解密的字符串</param>
        ///// <returns>解密成功返回解密后的字符串，失败返源串</returns>
        //public  string Decrypt(string toDecryptString)
        //{
        //    try
        //    {
        //        if (toDecryptString == null || toDecryptString == "" || toDecryptString == string.Empty)
        //        {
        //            return "";
        //        }
        //        byte[] rgbKey = Encoding.UTF8.GetBytes(key);
        //        byte[] rgbIV = IV;
        //        byte[] inputByteArray = Convert.FromBase64String(toDecryptString);
        //        DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
        //        MemoryStream mStream = new MemoryStream();
        //        CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
        //        cStream.Write(inputByteArray, 0, inputByteArray.Length);
        //        cStream.FlushFinalBlock();
        //        return Encoding.UTF8.GetString(mStream.ToArray(), 0, mStream.ToArray().Length);
        //    }
        //    catch
        //    {
        //        return toDecryptString;
        //    }
        //}

        ///// <summary>
        ///// DES加密方法
        ///// </summary>
        ///// <param name="toEncryptString">明文</param>
        ///// <param name="Key">密钥</param>
        ///// <param name="IV">向量</param>
        ///// <returns>密文</returns>
        //public static string Encrypt(string toEncryptString, string Key, string IV)
        //{
        //    //把密钥转换成字节数组
        //    byte[] bytesDESKey = ASCIIEncoding.ASCII.GetBytes(Key);
        //    //把向量转换成字节数组
        //    byte[] bytesDESIV = ASCIIEncoding.ASCII.GetBytes(IV);
        //    //声明1个新的DES对象
        //    DESCryptoServiceProvider desEncrypt = new DESCryptoServiceProvider();
        //    //开辟一块内存流
        //    MemoryStream msEncrypt = new MemoryStream();
        //    //把内存流对象包装成加密流对象
        //    CryptoStream csEncrypt = new CryptoStream(msEncrypt, desEncrypt.CreateEncryptor(bytesDESKey, bytesDESIV), CryptoStreamMode.Write);
        //    //把加密流对象包装成写入流对象
        //    StreamWriter swEncrypt = new StreamWriter(csEncrypt);
        //    //写入流对象写入明文
        //    swEncrypt.WriteLine(toEncryptString);
        //    //写入流关闭
        //    swEncrypt.Close();
        //    //加密流关闭
        //    csEncrypt.Close();
        //    //把内存流转换成字节数组，内存流现在已经是密文了
        //    byte[] bytesCipher = msEncrypt.ToArray();
        //    //内存流关闭
        //    msEncrypt.Close();
        //    //把密文字节数组转换为字符串，并返回
        //    return Encoding.UTF8.GetString(bytesCipher, 0, bytesCipher.Length);
        //}


        /// <summary>
        /// 3des二倍长加密
        /// </summary>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public  byte[] _3DES2Encrypt(byte[] key, byte[] iv, byte[] data)
        {
            byte[] key1 = new byte[8];
            Array.Copy(key, 0, key1, 0, 8);
            byte[] key2 = new byte[8];
            Array.Copy(key, 0, key2, 0, 8);
            byte[] data1 = EncryptECB(data, key1, iv);
            data1 = DecryptECB(data1, key2, iv);
            data1 = EncryptECB(data1, key1, iv);
            return data1;
        }
        /// <summary>
        /// 3des二倍长解密
        /// </summary>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public  byte[] _3DES2Descrypt(byte[] key, byte[] iv, byte[] data)
        {

            byte[] key1 = new byte[8];
            Array.Copy(key, 0, key1, 0, 8);
            byte[] key2 = new byte[8];
            Array.Copy(key, 0, key2, 0, 8);

            byte[] data1 = DecryptECB(data, key1, iv);
            data1 = EncryptECB(data1, key2, iv);
            data1 = DecryptECB(data1, key1, iv);
            return data1;
        }


        /// <summary>
        /// ECB解密
        /// </summary>
        /// <param name="encryptedDataBytes"></param>
        /// <param name="keys"></param>
        /// <returns></returns>
        public  byte[] DecryptECB(byte[] encryptedDataBytes, byte[] keys, Byte[] iv)
        {
            //Byte[] iv = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
            //Byte[] keys = System.Text.Encoding.UTF8.GetBytes(key.Substring(0, key.Length));

            //Byte[] encryptedDataBytes = System.Convert.FromBase64String(sourceData);
            MemoryStream tempStream = new MemoryStream(encryptedDataBytes, 0, encryptedDataBytes.Length);
            DESCryptoServiceProvider decryptor = new DESCryptoServiceProvider();
            decryptor.Mode = CipherMode.ECB;
            decryptor.Padding = PaddingMode.None;
            CryptoStream decryptionStream = new CryptoStream(tempStream, decryptor.CreateDecryptor(keys, iv), CryptoStreamMode.Read);
            //StreamReader allDataReader = new StreamReader(decryptionStream);
            byte[] data = new byte[encryptedDataBytes.Length];
            decryptionStream.Read(data, 0, data.Length);
            decryptionStream.Close();
            tempStream.Close();
            return data;

        }
        /// <summary>
        /// ECB加密
        /// </summary>
        /// <param name="sourceDataBytes"></param>
        /// <param name="keys"></param>
        /// <returns></returns>
        public  byte[] EncryptECB(byte[] sourceDataBytes, byte[] keys, Byte[] iv)
        {

            //Byte[] iv = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
            MemoryStream tempStream = new MemoryStream();
            //get encryptor and encryption stream
            DESCryptoServiceProvider encryptor = new DESCryptoServiceProvider();
            encryptor.Mode = CipherMode.ECB;
            encryptor.Padding = PaddingMode.None;
            CryptoStream encryptionStream = new CryptoStream(tempStream, encryptor.CreateEncryptor(keys, iv), CryptoStreamMode.Write);
            encryptionStream.Write(sourceDataBytes, 0, sourceDataBytes.Length);
            encryptionStream.FlushFinalBlock();
            encryptionStream.Close();
            byte[] encryptedDataBytes = tempStream.ToArray();
            tempStream.Close();
            return encryptedDataBytes;
        }

        /// <summary>
        /// 字符串转字节数组
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        public static byte[] strToToHexByte(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                hexString += " ";
            byte[] returnBytes = new byte[hexString.Length / 2];
            try
            {
                for (int i = 0; i < returnBytes.Length; i++)
                    returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            }
            catch (Exception ex)
            {

            }
            return returnBytes;
        }
        /// <summary>
        /// 字节数组转16进制字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string byteToHexStr(byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    returnStr += bytes[i].ToString("X2");

                }
            }
            return returnStr;
        }
        public string bb(byte[] aa,string mackey="")
        {


            byte[] MACKEY = strToToHexByte("73772126D3F9FEAB0000000000000000B93C28CD");
            //待计算数据
            byte[] data = aa;
            //进行分组
            int group = (data.Length + (8 - 1)) / 8;
            //偏移量
            int offset = 0;
            //输入计算数据
            byte[] edata = new byte[8];
            byte[] temp = new byte[8];
            for (int i = 0; i < group; i++)
            {
                temp = new byte[8];
                if (i == 0)
                {
                    Array.Copy(data, offset, edata, 0, 8);
                }
                if (i != group - 1)
                {
                    Array.Copy(data, offset, temp, 0, 8);
                    offset += 8;
                }
                else
                {//只有最后一组数据才进行填充0x00
                    Array.Copy(data, offset, temp, 0, data.Length - offset);
                }


                if (i != 0)
                {//只有第一次不做异或
                    edata = XOR(edata, temp);
                }

            }
            string gwfa = byteToHexStr(edata);
            byte[] ByteFoo = System.Text.Encoding.Default.GetBytes(gwfa);
            string TempStr = "";
            foreach (byte b in ByteFoo)
            {

                TempStr += b.ToString("X"); //X表示十六进制显示       
            }
            byte[] qianba = strToToHexByte(TempStr.Substring(0, 16));
            byte[] houba = strToToHexByte(TempStr.Substring(16, 16));
            qianba = new EncryptHelper()._3DES2Encrypt(MACKEY, new byte[1], qianba);
            edata = XOR(qianba, houba);
            edata = new EncryptHelper()._3DES2Encrypt(MACKEY, new byte[1], edata);
            string fvggg = byteToHexStr(edata);
            ByteFoo = System.Text.Encoding.Default.GetBytes(fvggg);
            TempStr = "";
            foreach (byte b in ByteFoo)
            {

                TempStr += b.ToString("X"); //X表示十六进制显示       
            }
            return TempStr.Substring(0, 16); ;

        }
        public static byte[] XOR(byte[] edata, byte[] temp)
        {
            byte[] result = new byte[8];
            for (int i = 0, j = result.Length; i < j; i++)
            {
                result[i] = (byte)(edata[i] ^ temp[i]);
            }
            return result;
        }
    }
}